package org.marcesher.blogcodeformatter.formatters;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class UnIndentFormatter implements IFormatter {
	static final String SEP = System.getProperty("line.separator");
	
	/**
	 * unindents the selection
	 * @param input the user's selected text
	 * @return the newly formatted string
	 */
	public  String format(String input, String fileName, String extension){		
		String linebreak = getLinebreakForFile(input);
		String[] lines = input.split(linebreak);
		String common = getCommonWhitespacePrefix(lines);
		//System.out.println("common: [" + common + "]");		
		return unindentAllLines(lines, common, linebreak);
	}

	/**
	 * @param lines all lines to format
	 * @param commonStart the pre-computed common whitespace for all lines in the user's selected input
	 * @param linebreak the linebreak character of the file whose input is being read
	 * @return a fully unindented set of lines
	 */
	private String unindentAllLines(String[] lines, String commonStart, String linebreak) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < lines.length; i++) {
			sb.append(unIndentLine(lines[i],commonStart,linebreak));			
		}
		return sb.toString().trim();
	}
	
	/**
	 * strips off the starting whitespace, the original trailing linebreak, and then appends a linebreak for the system the user is working on
	 * @param inputLine the line to be formatted
	 * @param commonStart the pre-computed common whitespace for all lines in the user's selected input
	 * @param linebreak the linebreak character of the file whose input is being read
	 * @return a string, formatted as described
	 */
	private String unIndentLine(String inputLine, String commonStart, String linebreak){
		return inputLine.replaceFirst(commonStart, "").replace(linebreak, "").concat(SEP);
	}
	
	/**
	 * @param lines the array of lines to interrogate
	 * @return the common whitespace prefix of all lines
	 */
	private String getCommonWhitespacePrefix(String[] lines){
		//get rid of any completely blank lines, as they will throw off the getCommonPrefix function
		List<String> newLines = new ArrayList<String>();
		for (int i = 0; i < lines.length; i++) {
			if(lines[i].trim().length()>0){
				newLines.add(lines[i]);
			}
		}
		String common = StringUtils.getCommonPrefix(newLines.toArray(new String[newLines.size()]));
		if(common.matches("^(\\s+)(.*)"))
			return common.replaceFirst("^(\\s+)(.*)", "$1");
		else
			return "";
	}
	/**
	 * finds one of the 3 different linebreak potentials in the source input: http://mindprod.com/jgloss/lineseparator.html. We can't simply use the system-specific linebreak since that is quite possibly not the linebreak used when creating the file
	 * @param input the string to interrogate
	 * @return the linebreak char(s) used for the input
	 */
	private String getLinebreakForFile(String input){
		if(input.contains("\r\n"))
			return "\r\n";
		else if(input.contains("\r"))
			return "\r";
		else
			return "\n";
	}
}
